import string
import copy
import scipy
import Tkinter, tkFileDialog
import numpy as np
import pandas as pd
from scipy.spatial.distance import cdist
import matplotlib.pyplot as plt
import os
import re
import sys
import cPickle
import glob
sys.path.append(os.path.abspath("C:\Users\Scherer Lab E\Documents\GitHub\Python_Data_Analysis"))
import common_functions
import half_nanoplate_functions as hnf
cd "K:\Pat's_Projects\ParticleTrajectoryData"
store = pd.HDFStore('half_nanoplate_dynamics_processed.h5', mode='r')
Using Stokes Law and the average velocity (of the arc) of the particle over the nanoplate to calculate the force of the trap on the particles.
'''Calculate the velocities over nanoplate and Stokes drag forces for each
velocity. Calculate the mean and deviation in the forces for each L'''
keys = store.index['key']
results = pd.DataFrame()
results['L'] = store.index['L']
velocity_list = []
force_list = []
mean_force = []
std_force = []
for i,key in enumerate(keys):
df = store.get(key).copy()
velocities = hnf.calc_velocities_consec_frames_in_theta(df, only_over_plate=True)
forces = hnf.calc_force_stokes_drag(velocities)
velocity_list.append(velocities)
force_list.append(forces)
mean_force.append(forces.mean())
std_force.append(forces.std())
'''Add columns for last frame on plate and first frame on glass in new
DataFrames'''
kinetic_data = []
keys = store.index['key']
for key in keys:
df = store.get(key).copy()
kinetic_data.append(hnf.add_barrier_crossing_index(df))
'''Fitting functions for dwell times'''
single_exp = lambda x, p1,p2: p1*np.exp(-p2*x)
double_exp = lambda x1, x2, p1,p2,p3: p1*(np.exp(-p2*x1) - np.exp(-p3*x2))
Set the cutoff for the attempts histogram for all experiments to be the same at 230 degrees
all_expts_dwell_time = []
for num, v in enumerate(kinetic_data):
# Apply selection criteria
temp_df = v[v['over_plate']==True]
temp_df = temp_df.drop_duplicates(['frame', 'track id'])
temp_df = temp_df.query('230 < theta < 280')
# Find the dwell time for each particle leaving the plate in the DataFrame
target_indices = temp_df[temp_df['last_frame_plate'] == True].index
one_expt_dwell_time = []
for target in target_indices:
dwell_time = hnf.trajectory_dwell_time_to_index(temp_df, target, max_frames_absent=5)
one_expt_dwell_time.append(dwell_time)
all_expts_dwell_time.append(one_expt_dwell_time)
cum_dwell_time = plt.figure(figsize=(8,8))
Ls = [1, 2, 3, 4, 5, 10]
theta_230_cutoff_dwell_time = pd.DataFrame()
theta_230_cutoff_dwell_time['L'] = results['L']
cum_dwell_times = {}
fit_dwell_times = {}
for num, v in enumerate(all_expts_dwell_time):
theta_230_cutoff_dwell_time.loc[num, 'mean_dwell_time'] = np.asarray(v).mean()
# Histogram
bins = hnf.hist_bin_optimization(v)
hist, bins = np.histogram(v, bins=bins)
mid_bins = (bins[:-1] + bins[1:])/2.0
d_t = 1 - np.cumsum(hist)/float(sum(hist))
if num == 0:
params, cov = scipy.optimize.curve_fit(single_exp, mid_bins, d_t, p0=[0.5,0.0095], maxfev=2000)
else:
params, cov = scipy.optimize.curve_fit(single_exp, mid_bins, d_t, maxfev=2000)
fit_x = np.linspace(min(mid_bins)*0.90, max(mid_bins)*1.10, 300)
fit_y = [single_exp(xp, params[0], params[1]) for xp in fit_x]
theta_230_cutoff_dwell_time.loc[num, 'decay'] = params[1]
# Put data in lists for later
cum_dwell_times['cdf_l'+str(Ls[num])] = d_t
cum_dwell_times['dwell_l'+str(Ls[num])] = mid_bins/90.0
fit_dwell_times['cdf_fit_l'+str(Ls[num])] = fit_y
fit_dwell_times['dwell_fit_l'+str(Ls[num])] = fit_x/90.0
# Plot
plt.subplot(3,2,num+1)
plt.plot(mid_bins/90.0, d_t, 'o')
plt.plot(fit_x/90.0, fit_y, 'k')
plt.title(keys[num])
plt.title('Cumulative Dwell Time L='+str(Ls[num]))
plt.xlabel('Dwell Time (sec)')
plt.ylabel('$1-\mathregular{CDF}$')
plt.tight_layout()
plt.show()
# save_dir = "C:\Users\Scherer Lab E\Dropbox\SPIE Presentation"
# cum_dwell_time.savefig(save_dir+"\cum_dwell_time_dist.pdf", dpi=800)
# cum_dwell_time.savefig(save_dir+"\cum_dwell_time_dist.png", dpi=800)
theta_230_cutoff_dwell_time
# Collect all model fit parameters in a dictionary
model_fit_params = {}
k_f = theta_230_cutoff_dwell_time['decay']*90.0
mean_force_list = np.asarray(mean_force)
std_dev_force_list = np.asarray(std_force)
fit_params = np.polyfit(mean_force_list[:-1]*10**12, np.log(k_f)[:-1], 1)
print fit_params
print "k_o = "+str(np.exp(fit_params[1]))+" s^-1"
print "x_b = "+str(fit_params[0]*298*1.38*10**(-23)*10**12)+" meters"
k_o = np.exp(fit_params[1])
x_b = fit_params[0]*298*1.38*10**(-23)*10**12
model_fit_params['bell_k_o'] = k_o
model_fit_params['bell_x_b'] = x_b
bell_model_fig = plt.figure()
plt.plot(mean_force_list[:-1]*10**12, k_f[:-1], 'bo')
plt.errorbar(mean_force_list[:-1]*10**12, k_f[:-1], xerr=std_dev_force_list[:-1]*10**12, linestyle='none')
fit_func = np.poly1d(fit_params)
plt.plot(np.linspace(0,0.25), np.exp(fit_func(np.linspace(0,0.25))), 'g')
plt.yscale('log')
plt.xlabel('Applied Force (pN)')
plt.ylabel('Dwell Time Decay Rate ($\mathregular{s}^{-1}$)')
plt.title('$k(F)$ vs Force')
chi2 = np.sum(((np.log(k_f)[:-1] - fit_func(mean_force_list[:-1]*10**12))**2)/(fit_params[0]*(std_dev_force_list[:-1]*10**12))**2)
print "Chi-squared fit: "+str(chi2)[:-1]
# save_dir = "C:\Users\Scherer Lab E\Dropbox\SPIE Presentation"
# bell_model_fig.savefig(save_dir+"\\bell_model_fit.pdf", dpi=800)
# bell_model_fig.savefig(save_dir+"\\bell_model_fit.png", dpi=800)
There is a paper written by Hummer and Szabo that describes an extension of Bell's Model within the context of single-molecule pulling experiments. The reference is:
The main I am trying to fit to my data is eqn 3 in the text. The reason why is because in the paper in Fig 4 the force versus rate looks similar to what I see for my data. The equation being fit is (different from paper because it is missing some symbols):
$k(F) = k_o\left(1 - \frac{\nu F x^\ddagger}{\Delta G^\ddagger}\right)^{\frac{1}{\nu}-1} e^{\beta \Delta G^\ddagger[1 - (1 - \nu F x^\ddagger / \Delta G^\ddagger)^{1/\nu}]}$
Where $k(F)$ is the rate as a function of force ($F$), $k_o$ is the rate at $F=0$, $x^\ddagger$ is the distances from the lowest point in the well to the transition state ($\Delta G^\ddagger$). $\nu$ describes the nature of the barrier. $\nu=1/2$ corresponds to the cusp free-energy surface while $\nu = 2/3$ corresponds to a linear-cubic free energy surface. At $\nu=1$ the equation reduces to the Bell Model. I try fitting this equation using $k_o, \Delta G^\ddagger,$ and $x^\ddagger$ as fitting parameters for different values of $\nu$.
def hum_szabo_unified_theory(force, k0, xdd, gdd):
first_multiple = k0 * (1.0 - (0.5*force*xdd/gdd))**(1.0/0.5 - 1.0)
exponent = np.exp((gdd/kbt)*(1.0 - (1.0 - (0.5*force*xdd/gdd))**(1.0/0.5)))
return first_multiple * exponent
kbt = 1.3806*10**(-23)*298
k_f = theta_230_cutoff_dwell_time['decay']*90.0
input_force = mean_force_list[:-1]
print k_f
fit_params, cov = scipy.optimize.curve_fit(hum_szabo_unified_theory, input_force, k_f[:-1], maxfev=2000000000, p0=[3*10**-4, 300*10**-9, 12*kbt])
print "k_o = "+str(fit_params[0])+" s^-1"
print "xdd = "+str(fit_params[1])+" meters"
print "del_G = "+str(fit_params[2]/kbt)+" kt"
print fit_params
print mean_force_list
plt.plot(mean_force_list[:-1]*10**12, k_f[:-1], 'bo')
plt.errorbar(mean_force_list[:-1]*10**12, k_f[:-1], xerr=std_dev_force_list[:-1]*10**12, linestyle='none')
fit_x = np.linspace(0,0.25*10**-12)
fit_y = hum_szabo_unified_theory(fit_x, *fit_params)
plt.plot(fit_x*10**12, fit_y, 'g')
plt.yscale('log')
plt.xlabel('Applied Force (pN)')
plt.ylabel('Dwell Time Decay Rate')
plt.title('$k(F)$ vs Force')
plt.xlim(0,0.25)
theo_y = hum_szabo_unified_theory(input_force, *fit_params)
theo_sigma = hum_szabo_unified_theory(std_dev_force_list[:-1], *fit_params)
chi2 = np.sum(((k_f[:-1] - theo_y)**2)/(theo_sigma)**2)
print "Reduced Chi-squared fit: "+str(chi2)[:-1]
model_fit_params['dhs_n0.5_k_o'] = fit_params[0]
model_fit_params['dhs_n0.5_xdd'] = fit_params[1]
model_fit_params['dhs_n0.5_del_g'] = fit_params[2]/kbt
def hum_szabo_unified_theory(force, k0, xdd, gdd):
first_multiple = k0 * (1.0 - ((2/3.0)*force*xdd/gdd))**(1.0/(2/3.0) - 1.0)
exponent = np.exp((gdd/kbt)*(1.0 - (1.0 - ((2/3.0)*force*xdd/gdd))**(1.0/(2/3.0))))
return first_multiple * exponent
k_f = theta_230_cutoff_dwell_time['decay']*90.0
input_force = mean_force_list[:-1]
print k_f
fit_params, cov = scipy.optimize.curve_fit(hum_szabo_unified_theory, input_force, k_f[:-1], maxfev=2000000000, p0=[1e-01, 1.28915220e-07, 3.05213988e-20])
print "k_o = "+str(fit_params[0])+" s^-1"
print "xdd = "+str(fit_params[1])+" meters"
print "del_G = "+str(fit_params[2]/kbt)+" kt"
print fit_params
hum_sza_fit = plt.figure()
plt.plot(mean_force_list[:-1]*10**12, k_f[:-1], 'bo')
plt.errorbar(mean_force_list[:-1]*10**12, k_f[:-1], xerr=std_dev_force_list[:-1]*10**12, linestyle='none')
fit_x = np.linspace(0,0.25*10**-12)
#fit_params = [1e-01, 1.28915220e-07, 3.05213988e-20]
fit_y = hum_szabo_unified_theory(fit_x, *fit_params)
plt.plot(fit_x*10**12, fit_y, 'k')
plt.yscale('log')
plt.xlabel('Applied Force (pN)')
plt.ylabel('Dwell Time Decay Rate ($\mathregular{s}^{-1}$)')
plt.title('$k(F)$ vs Force')
plt.xlim(0, 0.25)
theo_y = hum_szabo_unified_theory(input_force, *fit_params)
theo_sigma = hum_szabo_unified_theory(std_dev_force_list[:-1], *fit_params)
chi2 = np.sum(((k_f[:-1] - theo_y)**2)/(theo_sigma)**2)
print "Reduced Chi-squared fit: "+str(chi2)[:-1]
# save_dir = "C:\Users\Scherer Lab E\Dropbox\SPIE Presentation"
# hum_sza_fit.savefig(save_dir+"\hum_sza_fit.pdf", dpi=800)
# hum_sza_fit.savefig(save_dir+"\hum_sza_fit.png", dpi=800)
model_fit_params['dhs_n0.66_k_o'] = fit_params[0]
model_fit_params['dhs_n0.66_xdd'] = fit_params[1]
model_fit_params['dhs_n0.66_del_g'] = fit_params[2]/kbt
The reason for the cutoff of the curve at .37 pN is because the term in the exponent $(1 - \nu F x^\ddagger / \Delta G^\ddagger)^{1/\nu}$ becomes imaginary. For certain values of $F$ the term $1 - \nu F x^\ddagger / \Delta G^\ddagger$ becomes negative but it is being raised to an exponent of 3/2 (when $\nu$=2/3). When $\nu$=1/2 this problem doesn't occur because the term will always be squared.
I couldn't get the fit for the Bell Model to work with $\nu$ = 1
def hum_szabo_unified_theory(force, k0, xdd, gdd):
first_multiple = k0 * (1.0 - (1.0*force*xdd/gdd))**(1.0 - 1.0/1.0)
exponent = np.exp((gdd/kbt)*(1.0 - (1.0 - (1.0*force*xdd/gdd))**(1.0/1.0)))
return first_multiple * exponent
k_f = theta_230_cutoff_dwell_time['decay']*90.0
input_force = mean_force_list[:-1]
print k_f
fit_params, cov = scipy.optimize.curve_fit(hum_szabo_unified_theory, input_force, k_f[:-1], maxfev=2000000000, p0=[3*10**-4, 300*10**-9, 12*kbt])
print "k_o = "+str(fit_params[0])+" s^-1"
print "x_b = "+str(fit_params[1])+" meters"
print "del_G = "+str(fit_params[2])+" joules"
print fit_params
plt.plot(mean_force_list[:-1], k_f[:-1], 'bo')
plt.errorbar(mean_force_list[:-1], k_f[:-1], xerr=std_dev_force_list[:-1], linestyle='none')
fit_x = np.linspace(0,0.5*10**-12)
fit_y = hum_szabo_unified_theory(fit_x, *fit_params)
plt.plot(fit_x, fit_y, 'g')
plt.yscale('log')
plt.xlabel('Applied Force (pN)')
plt.ylabel('log(Dwell Time Decay Rate)')
plt.title('$log(k(F))$ vs Force')
def hum_szabo_unified_theory(force, k0, xdd, gdd):
first_multiple = k0 * (1.0 - ((1/2.0)*force*xdd/gdd))**(1.0/(1/2.0) - 1.0)
exponent = np.exp((gdd/kbt)*(1.0 - (1.0 - ((1/2.0)*force*xdd/gdd))**(1.0/(1/2.0))))
return first_multiple * exponent
bell_hum_szabo_graph = {}
k_f = theta_230_cutoff_dwell_time['decay']*90.0
mean_force_list = np.asarray(mean_force)
std_dev_force_list = np.asarray(std_force)
fit_params = np.polyfit(mean_force_list[:-1]*10**12, np.log(k_f)[:-1], 1)
print fit_params
print "k_o = "+str(np.exp(fit_params[1])*90.0)+" s^-1"
print "x_b = "+str(fit_params[0]*298*1.38*10**(-23)*10**12)+" meters"
bell_hum_fits = plt.figure()
plt.plot(mean_force_list[:-1]*10**12, k_f[:-1], 'bo')
plt.errorbar(mean_force_list[:-1]*10**12, k_f[:-1], xerr=std_dev_force_list[:-1]*10**12, linestyle='none')
fit_func = np.poly1d(fit_params)
plt.plot(np.linspace(0,0.25), np.exp(fit_func(np.linspace(0,0.25))), 'g')
plt.yscale('log')
plt.xlabel('Applied Force (pN)')
plt.ylabel('Dwell Time Decay Rate')
plt.title('$k(F)$ vs Force')
bell_hum_szabo_graph['avg_force'] = mean_force_list[:-1]*10**12
bell_hum_szabo_graph['std_force'] = std_dev_force_list[:-1]*10**12
bell_hum_szabo_graph['k_f'] = k_f[:-1]
bell_hum_szabo_graph['bell_x'] = np.linspace(0,0.25)
bell_hum_szabo_graph['bell_y'] = np.exp(fit_func(np.linspace(0,0.25)))
chi2 = np.sum(((np.log(k_f)[:-1] - fit_func(mean_force_list[:-1]*10**12))**2)/(fit_params[0]*(std_dev_force_list[:-1]*10**12))**2)
print "Chi-squared fit: "+str(chi2)[:-1]
k_f = theta_230_cutoff_dwell_time['decay']*90.0
input_force = mean_force_list[:-1]
print k_f
fit_params, cov = scipy.optimize.curve_fit(hum_szabo_unified_theory, input_force, k_f[:-1], maxfev=2000000000, p0=[1e-01, 1.28915220e-07, 3.05213988e-20])
print "k_o = "+str(fit_params[0])+" s^-1"
print "xdd = "+str(fit_params[1])+" meters"
print "del_G = "+str(fit_params[2]/kbt)+" kt"
print fit_params
#plt.plot(mean_force_list[:-1]*10**12, k_f[:-1], 'bo')
#plt.errorbar(mean_force_list[:-1]*10**12, k_f[:-1], xerr=std_dev_force_list[:-1]*10**12, linestyle='none')
fit_x = np.linspace(0,0.25*10**-12)
#fit_params = [1e-01, 1.28915220e-07, 3.05213988e-20]
fit_y = hum_szabo_unified_theory(fit_x, *fit_params)
plt.plot(fit_x*10**12, fit_y, 'k')
plt.yscale('log')
plt.xlabel('Applied Force (pN)')
plt.ylabel('Dwell Time Decay Rate ($\mathregular{s}^{-1}$)')
plt.title('$k(F)$ vs Force')
plt.ylim(10**-1,10**2)
bell_hum_szabo_graph['hum_szabo_x'] = fit_x*10**12
bell_hum_szabo_graph['hum_szabo_y'] = fit_y
theo_y = hum_szabo_unified_theory(input_force, *fit_params)
theo_sigma = hum_szabo_unified_theory(std_dev_force_list[:-1], *fit_params)
chi2 = np.sum(((k_f[:-1] - theo_y)**2)/(theo_sigma)**2)
print "Reduced Chi-squared fit: "+str(chi2)[:-1]
# save_dir = "C:\Users\Scherer Lab E\Dropbox\SPIE Presentation"
# bell_hum_fits.savefig(save_dir+"\\bell_hum_fits.pdf", dpi=800)
# bell_hum_fits.savefig(save_dir+"\\bell_hum_fits.png", dpi=800)
'''Save the k(F) vs Force for Bell and Hummer Szabo data for the paper'''
import cPickle
pickle_file = open("C:\Users\Scherer Lab E\Box Sync\Half-Nanoplate\Figures and Data\Data\\bell_hum_szabo_fit.pkl", 'w')
cPickle.dump(bell_hum_szabo_graph, pickle_file)
pickle_file.close()
'''Save the fit parameters from the Bell and Hummer Szabo models'''
import cPickle
pickle_file = open("C:\Users\Scherer Lab E\Box Sync\Half-Nanoplate\Figures and Data\Data\\bell_hum_szabo_model_fit_params.pkl", 'w')
cPickle.dump(model_fit_params, pickle_file)
pickle_file.close()
store.close()